#SingleInstance force
; #NoTrayIcon ; 隐藏系统托盘图标，编译的时候开启


VerUpdates:=[
    "v2.0 支持ahk2.0",
    "v2.1 Caps+V弹出最新版本信息",
    "v2.2 Caps+F弹出映射表",
    "v2.3 Combine函数支持Win组合键（Win+L除外）",
    "v2.4 Caps+P截屏",
    "v2.5 支持OneNote中光标的上下移动",
    "v2.6 WSAD -> 上下左右",
    "v2.7 ^+`打开任务管理器",
    "v2.8 !`映射为!{Esc}",
    "v2.9 wSAD -> 滚轮的上下左右",
    "v2.10 '-> 鼠标右键"
]

BoxIt(){
    
    MapInfo:="
(Join`n
Tab       | CapsLock
1~9 0 - = | F1~F9 F10 F11 F12
↑↓←→      | MouseMove
shift+↑↓←→| MouseMove Fast
alt+↑↓←→| MouseMove Slow
HJKL | ←↓↑→
WSAD | Wheel ↑↓←→
U I | PgDn  PgUp
Y O | Home  End
M , | Delete a char
N . | Delete a word
B / | Delete to end
Backspace | Del
Space | Esc
P or Insert | PrintScreen
Q or Esc | ``
\ | Click Continuously
Enter | Click Once (and stop clicking)
' | Clieck (Right)
^+`` | ^+{Esc}
V | Brief Version Info
^V | Detailed Mapping
)"
    myGui := Gui()
    ; myGui.OnEvent("Close", GuiClose)
    table := myGui.Add("Listview", "r30", ["     Original Key     ", "     Mapped Key     "])
    Loop Parse, MapInfo, "`n", "`r"
        {
        data := StrSplit(A_LoopField,"|") ; just an example
        table.Add("", data[1], data[2])
        }
    myGui.Show()
    Return
}


ShowVersion(){
    ShiftState:=GetKeyState("Shift", "P")
    if (ShiftState)
        BoxIt()
    else
        MsgBox(VerInfo)
}

VerInfo:=VerUpdates[VerUpdates.Length]
CapsLock & v:: ShowVersion()
CapsLock & r:: Reload()

SetCapsLockState("AlwaysOff")
CapsLock & Tab::
{
    CapsLockState := GetKeyState("CapsLock", "T")  ; 获取当前CapsLock状态
    SetCapsLockState(CapsLockState ? "AlwaysOff" : "AlwaysOn")
}

MoveMouseDirection(x, y) {
    shift := GetKeyState("Shift", "P")
    alt := GetKeyState("Alt", "P")
    ; 根据Shift和Alt状态计算移动量
    multiplier := shift ? 100 : (alt ? 1 : 10)
    MouseMove(x * multiplier, y * multiplier, 0, "R")
}
CapsLock & Up:: MoveMouseDirection(0, -1)
CapsLock & Down:: MoveMouseDirection(0, 1)
CapsLock & Left:: MoveMouseDirection(-1, 0)
CapsLock & Right:: MoveMouseDirection(1, 0)

global clicking := false
DoClick(){
    global clicking
    if (clicking)
    {
        SendEvent("{Blind}{LButton down}")
        SendEvent("{Blind}{LButton up}")
    }
}
CapsLock & \::
{
    global clicking
    clicking := true
    SetTimer(DoClick, 100)
    return
}
CapsLock & Enter::
{
    global clicking
    clicking := true
    DoClick()
    clicking := false
    SetTimer(DoClick, 0)
    return
}

; Delete
CapsLock & ,:: Combine("Del")              ; , = Del char after
CapsLock & .::Send("^{Del}")             ; . = Del word after
CapsLock & /::Send("+{End}{Del}")        ; / = Del all  after

; Backspace
CapsLock & m:: Combine("BS")               ; m = Del char before;
CapsLock & n::Send("^{BS}")              ; n = Del word before;
CapsLock & b::Send("+{Home}{Del}")       ; b = Del all  before;




; F{num}
CapsLock & 1:: Combine("F1")
CapsLock & 2:: Combine("F2")
CapsLock & 3:: Combine("F3")
CapsLock & 4:: Combine("F4")
CapsLock & 5:: Combine("F5")
CapsLock & 6:: Combine("F6")
CapsLock & 7:: Combine("F7")
CapsLock & 8:: Combine("F8")
CapsLock & 9:: Combine("F9")
CapsLock & 0:: Combine("F10")
CapsLock & -:: Combine("F11")
CapsLock & =:: Combine("F12")

; ↑↓←→
CapsLock & h::Combine("left")
CapsLock & l::Combine("right")
CapsLock & k::Combine("up")
CapsLock & j::Combine("down")
CapsLock & y::Combine("Home")
CapsLock & o::Combine("End")
CapsLock & u::Combine("PgDn")
CapsLock & i::Combine("PgUp")

; Esc
CapsLock & Space::Combine("Esc")

CapsLock & q::Combine("``")
CapsLock & BACKSPACE::Combine("Insert")

CapsLock & Insert::Combine("PrintScreen")
CapsLock & p::Combine("PrintScreen")

CapsLock & Esc::Combine("``")



Combine(action){
    ShiftState := GetKeyState("Shift", "P")
    AltState := GetKeyState("Alt", "P")
    ControlState := GetKeyState("Control", "P")
    WinState := GetKeyState("LWin", "P") ; 检查左Win键的状态

    ; 根据各个修饰键的状态构建发送字符串
    modifiers := ""
    if (ShiftState)
        modifiers .= "+"
    if (AltState)
        modifiers .= "!"
    if (ControlState)
        modifiers .= "^"
    if (WinState)
        modifiers .= "#"

    ; 使用构建好的修饰键字符串发送action
    Send(modifiers "{" action "}")
}


; for MobaXterm, use ctrl+backsace to delte a word
#HotIf WinActive("ahk_exe MobaXterm.exe", )
^Backspace::
{ ; V1toV2: Added bracket
    Send("^w")
    Return
} ; V1toV2: Added bracket in the end
#HotIf


; https://stackoverflow.com/questions/44170454/up-down-key-not-working-in-onenote-2016-for-autohotkey
; CapsLock & k::ControlSend, OneNote::DocumentCanvas1, {Up}
#HotIf WinActive("ahk_exe ONENOTE.exe")
    CapsLock & j::ControlSend "{Down}", "OneNote::DocumentCanvas1"
    CapsLock & k::ControlSend "{Up}", "OneNote::DocumentCanvas1"
#HotIf


^+`::Send("^+{Esc}")
!`::Send("!{Esc}")




; CapsLock & w::Combine("up")
; CapsLock & s::Combine("down")
; CapsLock & a::Combine("left")
; CapsLock & d::Combine("right")
CapsLock & w::WheelAction("{WheelUp}")
CapsLock & s::WheelAction("{WheelDown}")
CapsLock & a::WheelAction("{WheelLeft}")
CapsLock & d::WheelAction("{WheelRight}")

WheelAction(action){
    shift:=GetKeyState("Shift", "P")
    alt:=GetKeyState("Alt", "P")
    repeat_times := shift?3:(alt?1:2)
    Loop(repeat_times){
        Send(action)
    }
    
}

CapsLock & '::Click("right")
